﻿using apiframworkTest.Models;
using commonFramwork.Log;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using System.Web.Security;


namespace apiframworkTest.Extend
{
    public class MyuAuthAttribute : AuthorizeAttribute
    {
        private static MyuLogger loger = new MyuLogger(typeof(MyuAuthAttribute));
        public override void OnAuthorization(HttpActionContext actionContext)
        {



            #region JWT鉴权
            var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
            bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
            if (isAnonymous)
            {
                base.OnAuthorization(actionContext);
            }
            else
            {
                var token = actionContext.Request.Headers.Where(x => x.Key == "auth").FirstOrDefault().Value.FirstOrDefault();
                if (!string.IsNullOrEmpty(token))
                {
                    try
                    {
                        if (isAnonymous)
                        {
                            base.OnAuthorization(actionContext);
                        }
                        else
                        {
                            string secureKey = System.Configuration.ConfigurationManager.AppSettings["SecureKey"];
                            var builder = new JWT.Builder.JwtBuilder();
                            var authInfo = builder.Decode<AuthInfo>(token);

                            if (authInfo != null)
                            {
                                base.IsAuthorized(actionContext);
                            }
                            else
                            {
                                HandleUnauthorizedRequest(actionContext);
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //鉴权失败
                        HandleUnauthorizedRequest(actionContext);
                    }

                }
                else
                {
                    HandleUnauthorizedRequest(actionContext);
                }
            }
            #endregion


            #region  basic 鉴权

            ////从http请求的头里面获取身份验证信息，验证是否是请求发起方的ticket
            //var authorization = actionContext.Request.Headers.Authorization   ;
            //if ((authorization != null) && (authorization.Parameter != null))
            //{
            //    //解密用户ticket,并校验用户名密码是否匹配
            //    var encryptTicket = authorization.Parameter;
            //    if (ValidateTicket(encryptTicket))
            //    {
            //        base.IsAuthorized(actionContext);
            //    }
            //    else
            //    {
            //        HandleUnauthorizedRequest(actionContext);
            //    }
            //}
            ////如果取不到身份验证信息，并且不允许匿名访问，则返回未验证401
            //else
            //{
            //    var attributes = actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().OfType<AllowAnonymousAttribute>();
            //    bool isAnonymous = attributes.Any(a => a is AllowAnonymousAttribute);
            //    if (isAnonymous) base.OnAuthorization(actionContext);
            //    else HandleUnauthorizedRequest(actionContext);
            //}

            #endregion

        }



        //校验用户名密码（正式环境中应该是数据库校验）
        private bool ValidateTicket(string encryptTicket)
        {
            //解密Ticket
            var strTicket = FormsAuthentication.Decrypt(encryptTicket).UserData;

            //从Ticket里面获取用户名和密码
            var index = strTicket.IndexOf("&");
            string strUser = strTicket.Substring(0, index);
            string strPwd = strTicket.Substring(index + 1);

            if (strUser == "admin" && strPwd == "123456")
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        //public override Task OnAuthorizationAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
        //{
        //    // 这是一个基本例子，使用的ASP.NET Forms 身份验证
        //    var context = HttpContext.Current;
        //    if (SkipAuthorization(actionContext))
        //    {
        //        return Task.Run(() => { loger.Info("不需登录"); }); 
        //    }
        //    if (context.User.Identity.IsAuthenticated == false)
        //    {
        //        this.PreUnauthorized(actionContext);
        //        return Task.Run(() => { loger.Info("鉴权失败"); });
        //    }
        //    return Task.Run(() => { loger.Info("鉴权成功"); });
        //}

        private void PreUnauthorized(HttpActionContext actionContext)
        {
            // 如果用户没有登录，则返回一个通用的错误Model
            actionContext.Response = actionContext.Request.CreateResponse(
                HttpStatusCode.Unauthorized,
                new AjaxModel
                {
                    StatusCode = 401,
                    Message = "该操作需要用户登录"
                });
        }

        /// <summary>
        /// AllowAnonymous排除
        /// </summary>
        /// <param name="actionContext"></param>
        /// <returns></returns>
        private bool SkipAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
        {
            Contract.Assert(actionContext != null);
            return actionContext.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any()
            || actionContext.ControllerContext.ControllerDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
        }
    }
}